[アップデート] API で非同期な SQL クエリが実行できる!Amazon Redshift で Data API が利用可能になりました
先日のアップデートで Amazon Redshift で Data API が利用可能になりました。
Data API サポートによるメリット
ドライバーが不要!
従来、Redshift クラスターに接続するには JDBC/ODBC といったドライバーを介して SQL クライアントツールで接続していたかと思います。
Data API はその名のとおり API によって SQL ステートメントを実行することが出来ますので、クライアント環境にドライバーのインストールは必要ありません。Amazon EventBridge によるイベントまたはスケジュールをトリガーとして Lambda や AppSync でクエリ、ロード、アンロードといった実装をシンプルに組むことができます。
IAM による接続権限の管理
Data API は IAM 認証または AWS Secrets Manager を利用します。データベース接続のためにユーザごとの認証情報を管理する必要はありません。他の AWS リソース同様に IAM の権限管理によって Redshift クラスターへの接続管理を行うことができます。
非同期処理!
Data API は非同期で動作します。イベントやスケジュールによってトリガーされた SQL ステートメント の結果をあとから取得することが可能です。クエリ結果は 24 時間保存されます。
非同期に処理されるということは、例えば Lambda で大きなデータのアンロードなどを Data API で実行しても API を受け付けたというレスポンスが即時返るだけです。Lambda のタイムアウトも気になりません。あとは Step Functions で定期的に ステートメントのステータスをウォッチし、完了ステータスに変わったら後続処理、といった利用も可能になりそうですね。
対応リージョン
Data API は AWS GovCloud および大阪ローカルリージョンを除く、すべてのリージョンで利用可能です。
Data API における考慮事項
Data API を利用される場合、以下の考慮事項にお気をつけください。
- クエリの最大期間は 24 時間
- クエリ結果の最大保持期間は 24 時間
- クエリ結果の最大サイズは 100 MBです。100 MBを超えるレスポンスデータを返す場合、呼び出しは終了します。
- クエリステートメントの最大サイズは 100 KB
- クラスターが VPC 内にあること
- Data APIは、次のノードタイプの単一ノードおよび複数ノードのクラスターに使用できます
- dc2.large
- dc2.8xlarge
- ds2.xlarge
- ds2.8xlarge
- ra3.4xlarge
- ra3.16xlarge
やってみる
検証環境
今回は以下の環境で検証しています。
- 東京リージョン
- クラスター:
dc2.large
単一ノード
Secrets Manager に認証情報を登録
今回は Secrets Manager を使って Data API を実行しますので、まず認証情報を登録します。
Secrets Manager の管理コンソールを開き [新しいシークレットを保存する] をクリックします。シークレットの種類は [Redshiftクラスターの認証情報] を選択し、ユーザー名およびパスワードを入力します。シークレットがアクセスする Redshift クラスターを選択し、[次]へ。
シークレット名およびタグのキーに RedshiftDataFullAccess
を指定し、[次]へ。
AWS 管理ポリシー AmazonRedshiftDataFullAccess
を利用する場合は、タグキーに RedshiftDataFullAccess
が付与されているシークレットのみ secretsmanager:GetSecretValue
アクションが許可されています。別途ポリシーを作成し、タグベースの権限管理を利用しない場合は設定不要です。
{ "Sid": "SecretsManagerPermissions", "Action": [ "secretsmanager:GetSecretValue" ], "Effect": "Allow", "Resource": "*", "Condition": { "StringLike": { "secretsmanager:ResourceTag/RedshiftDataFullAccess": "*" } } },
今回は特に指定しませんが、シークレット側でリソースポリシーを設定しアクセス管理することも可能です。
必要に応じてシークレットを自動ローテーションすることも可能ですが、今回は無効のまま [次] へ進み、[保存] します。
Data API で SQL を実行
今回は AWS CLI を使用します。AWS CLI は執筆時点の最新バージョンにアップデートしています。また、実行環境の IAM ロールには AmazonRedshiftDataFullAccess
ポリシーのみをアタッチしています。
$ aws --version aws-cli/2.0.48 Python/3.7.3 Linux/4.14.193-149.317.amzn2.x86_64 exe/x86_64.amzn.2
Data API for Redshift では「Data API を有効化する」といった操作は必要ないようです。クラスターを作成すると自動的に Data API 用のエンドポイントが利用可能でした。(Data API for Aurora Serverless では有効化/無効化を選択できます)
SQL ステートメントの実行
SQL ステートメントの実行は aws redshift-data execute-statement
を使用します。--secret
は先程作成したシークレットの ARN を指定し、--sql
で実行したい SQL クエリを記述します。
また Data API は非同期であるためコマンドのレスポンスは API 実行に対するレスポンスであって、SQL クエリの実行結果ではないことに注目ください。
$ aws redshift-data execute-statement ¥ --secret arn:aws:secretsmanager:ap-northeast-1:12345678901:secret:data-api-5LCD8Q ¥ --cluster-identifier redshift-cluster-1 ¥ --sql "select * from stl_query limit 1" ¥ --database dev ClusterIdentifier: redshift-cluster-1 CreatedAt: '2020-09-11T17:01:41.171000+00:00' Database: dev Id: b9ffc607-9cce-4283-839b-c64ae21e2931 SecretArn: arn:aws:secretsmanager:ap-northeast-1:12345678901:secret:data-api-5LCD8Q
SQL ステートメントの一覧
実行した SQL ステートメントに関する一覧は aws redshift-data list-statements
で表示できます。実行結果はこの Id
を使って取得します。
$ aws redshift-data list-statements --status ALL Statements: - CreatedAt: '2020-09-11T16:50:23.351000+00:00' Id: f00188ec-e89d-491c-80d5-2444503a6cb2 QueryString: select * from stl_query limit 1 SecretArn: arn:aws:secretsmanager:ap-northeast-1:12345678901:secret:data-api-5LCD8Q Status: FINISHED UpdatedAt: '2020-09-11T16:50:25.030000+00:00' - CreatedAt: '2020-09-11T17:01:41.171000+00:00' Id: b9ffc607-9cce-4283-839b-c64ae21e2931 QueryString: select * from stl_query limit 1 SecretArn: arn:aws:secretsmanager:ap-northeast-1:12345678901:secret:data-api-5LCD8Q Status: FINISHED UpdatedAt: '2020-09-11T17:01:42.052000+00:00'
SQL ステートメントの結果取得
SQL ステートメントの実行結果を取得するには aws redshift-data get-statement-result
に SQL ステートメントの ID を指定します。
$ aws redshift-data get-statement-result --id b9ffc607-9cce-4283-839b-c64ae21e2931 ColumnMetadata: - isCaseSensitive: false isCurrency: false isSigned: true label: userid length: 0 name: userid nullable: 0 precision: 10 scale: 0 schemaName: pg_catalog tableName: stll_query typeName: int4 (後略)
CloudTrail に記録されること、されないこと
Data API へのリクエストは CloudTrail に記録されます。誰が Data API を使って、いつ、どのステートメントを実行したか知ることが出来ます。ただし --sql
の内容は ***OMITTED***
という形式でマスキングされるため CloudTrail で SQL クエリを知ることは出来ないようです。
{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROXXXXXXXXXXXXXXXXXX:i-00f8d3102bd7cabb9", "arn": "arn:aws:sts::012345678901:assumed-role/dataapi/i-00f8d3102bd7cabb9", "accountId": "012345678901", "accessKeyId": "ASIXXXXXXXXXXXXXXXXXX", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROXXXXXXXXXXXXXXXXXX", "arn": "arn:aws:iam::012345678901:role/dataapi", "accountId": "012345678901", "userName": "dataapi" }, "webIdFederationData": {}, "attributes": { "mfaAuthenticated": "false", "creationDate": "2020-09-11T16:37:39Z" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2020-09-11T16:50:24Z", "eventSource": "redshift-data.amazonaws.com", "eventName": "ExecuteStatement", "awsRegion": "ap-northeast-1", "sourceIPAddress": "AWS Internal", "userAgent": "aws-cli/2.0.48 Python/3.7.3 Linux/4.14.193-149.317.amzn2.x86_64 exe/x86_64.amzn.2 command/redshift-data.execute-statement", "requestParameters": { "clusterIdentifier": "redshift-cluster-1", "database": "dev", "secretArn": "arn:aws:secretsmanager:ap-northeast-1:012345678901:secret:data-api-5LCD8Q", "sql": "***OMITTED***" }, "responseElements": { "clusterIdentifier": "redshift-cluster-1", "createdAt": "Sep 11, 2020 4:50:23 PM", "database": "dev", "id": "f00188ec-e89d-491c-80d5-2444503a6cb2", "secretArn": "arn:aws:secretsmanager:ap-northeast-1:012345678901:secret:data-api-5LCD8Q" }, "requestID": "78e7fe0b-68c6-4f51-ac8a-89b09adb3f31", "eventID": "77926415-834c-44ea-82f5-5d3882b75bd3", "readOnly": false, "eventType": "AwsApiCall", "recipientAccountId": "012345678901" }
簡単ではありますが、検証は以上です!
さいごに
ついに Redshift にも Data API が来ましたね。ドライバーのインストールが不要で、認証情報の管理もシンプルなので非常に簡単に Redshift クラスターの SQL クライアント環境が準備できます。
Data API といえば Aurora Serverless が一足先に対応しています。Data API for Aurora Serverless は同期的に処理されるのに対して、Data API for Redshift は非同期的に処理される点はお気をつけください!
以上!大阪オフィスの丸毛(@marumo1981)でした!